export class MergeObjectUtils {

    /**
     * 浅度合并对象（仅对对象普通属性深度合并，如果属性值是对象或数组，会复制引用覆盖目标对象中的数组）
     *
     * @param target 目标对象，保留额外属性
     * @param source 源对象，用于提供新值
     * @returns 合并后的对象
     */
    static shallowMerge<T extends Record<string, any>>(target: T, source: Partial<T>): T {
        if (!source) {
            return target;
        }

        for (const key in source) {
            if (!Object.prototype.hasOwnProperty.call(source, key)) {
                continue;
            }

            const sourceValue = source[key];
            const targetValue = target[key];

            if (sourceValue === undefined) {
                // 如果源对象的属性值为 undefined，则删除目标对象的对应属性
                delete target[key];
            } else if (
                typeof sourceValue === 'object'
                && sourceValue !== null
                && !Array.isArray(sourceValue)
                && typeof targetValue === 'object'
                && targetValue !== null
                && !Array.isArray(targetValue)) {
                // 如果属性值是对象且不是数组，递归合并
                this.shallowMerge(targetValue, sourceValue);
            } else {
                // 否则直接赋值（数组、数值、字符串等）
                target[key] = sourceValue as T[typeof key];
            }
        }
        return target;
    }

    /**
     * 深度合并对象，对于数组也会递归深度合并
     *
     * @param target 目标对象
     * @param source 源对象
     * @returns 合并后的对象
     */
    static deepMerge<T extends Record<string, any>>(target: T, source: Partial<T>): T {
        if (!source) {
            return target;
        }

        for (const key in source) {
            if (!Object.prototype.hasOwnProperty.call(source, key)) {
                continue;
            }

            const sourceValue = source[key];
            const targetValue = target[key];

            if (sourceValue === undefined) {
                // 如果源对象的属性值为 undefined，则删除目标对象的对应属性
                delete target[key];
            } else if (
                typeof sourceValue === 'object'
                && sourceValue !== null
                && typeof targetValue === 'object'
                && targetValue !== null) {
                if (Array.isArray(sourceValue)) {
                    // 如果是数组，递归合并数组中的每一项
                    target[key] = this.mergeArrays(targetValue as any[], sourceValue as any[]) as T[typeof key];
                } else {
                    // 如果是对象，深度递归合并
                    this.deepMerge(targetValue, sourceValue);
                }
            } else {
                // 否则直接赋值
                target[key] = sourceValue as T[typeof key];
            }
        }
        return target;
    }

    /**
     * 深度合并数组
     *
     * @param targetArray 目标数组
     * @param sourceArray 源数组
     * @returns 合并后的数组
     */
    static mergeArrays<T extends any[]>(targetArray: T, sourceArray: T): T {
        // 复制目标数组
        const result = [...targetArray];

        sourceArray.forEach((sourceItem, index) => {
            const targetItem = result[index];

            if (typeof sourceItem === 'object' && sourceItem !== null) {
                if (Array.isArray(sourceItem)) {
                    // 如果数组项是数组，递归深度合并
                    result[index] = this.mergeArrays(targetItem || [], sourceItem) as T[number];
                } else if (typeof targetItem === 'object' && targetItem !== null) {
                    // 如果数组项是对象，递归深度合并
                    result[index] = this.deepMerge({...targetItem}, sourceItem);
                } else {
                    // 否则直接赋值
                    result[index] = sourceItem;
                }
            } else {
                // 否则直接赋值
                result[index] = sourceItem;
            }
        });
        return result as T;
    }
}
